#include "base/at_exit.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/process_util.h"
#include "base/message_loop.h"
#include "base/string_number_conversions.h"
#include "common/defines.h"
#include "work_enviroment.h"
#include "process_singleton.h"
#include "utils.h"

#pragma comment(lib, "Psapi.lib")
#pragma comment(lib, "Dbghelp.lib")
#pragma comment(lib, "base.lib")
#pragma comment(lib, "ipc.lib")
#pragma comment(lib, "base_i18n.lib")
#pragma comment(lib, "net.lib")
#pragma comment(lib, "googleurl.lib")
#pragma comment(lib, "icui18n.lib")
#pragma comment(lib, "sdch.lib")
#pragma comment(lib, "icuuc.lib")
#pragma comment(lib, "modp_b64.lib")
#pragma comment(lib, "zlib.lib")
#pragma comment(lib, "Ws2_32.lib")

using namespace dl;

namespace {
#pragma optimize("", off)
void InvalidParameter(const wchar_t* expression, const wchar_t* function,
	const wchar_t* file, unsigned int line,
	uintptr_t reserved) {
		__debugbreak();
		_exit(1);
}

void PureCall() {
	__debugbreak();
	_exit(1);
}
#pragma optimize("", on)
}  // namespace

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpCmdLine*/, int /*nCmdShow*/) {
	_set_invalid_parameter_handler(InvalidParameter);
	_set_purecall_handler(PureCall);
	_set_new_mode(1);
	base::EnableTerminationOnHeapCorruption();

  // 设置主线程名称
  base::PlatformThread::SetName("MainThread");

	CommandLine::Init(0, NULL);
	base::AtExitManager exit_manager;

	// 获取管道名和进程ID
	CommandLine* cl = CommandLine::ForCurrentProcess();
	std::string name = cl->GetSwitchValueASCII(kChannelName);
	if (name.empty()) return 0;

	// 进程互斥
	ProcessSingleton singleton;
	if (singleton.FoundOtherProcessWindow()) {
		singleton.NotifyOtherProcess(name);
		return 0;
	}

  // 主线程为UI线程
	MessageLoopForUI main_msg_loop;
	WorkEnviroment work_enviroment(&main_msg_loop);
  work_enviroment.CreateChannel(name);
	singleton.SetNotificationCallback(base::Bind(&WorkEnviroment::CreateChannel,
		                                           base::Unretained(&work_enviroment)));
	main_msg_loop.Run();

	return 1;
}
